package br.com.canvasForAll.model.dao;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;
import javax.inject.Named;
import javax.persistence.NoResultException;
import javax.persistence.Query;

import br.com.canvasForAll.model.entity.Canvas;
import br.com.canvasForAll.model.entity.Perfil;
import br.com.canvasForAll.model.generic.dao.GenericCrudDao;
import br.com.canvasForAll.model.repository.CanvasRepository;

@Stateless
@Named(value="canvasRepository")
public class CanvasDao extends GenericCrudDao<Canvas> implements CanvasRepository {
	
	public CanvasDao(){
		super(Canvas.class);
	}

	@Override
	public Canvas obterId(Long entityId) throws Exception {
		return super.obterPorId(entityId);
	}
	
	@Override
	public Canvas obterPorIds(Long id, Long idMobile) throws Exception {
		Canvas c = null;
		
		try{
			if(id != null && idMobile != null){
				Query query = em.createQuery("SELECT c FROM Canvas WHERE c.id = :id AND c.idMobile = :idMobile");
				query.setParameter("id", id);
				query.setParameter("idMobile", idMobile);

				c = (Canvas) query.getSingleResult();
			}

		} catch (NoResultException e){
			c = new Canvas();
		}
		
		return c;
	}

	@Override
	public List<Canvas> obterExemplo(String namedQuery, Map<String, Object> parametros) throws Exception {
		return super.obterPorExemplo(namedQuery, parametros);
	}
	
	/**
	 * Método para retornar todos os CANVAS ao qual determinado perfil é responsável
	 * @param PERFIL
	 * @return COLLECTION<CANVAS>
	 * @exception Exception
	 * */
	@SuppressWarnings("unchecked")
	@Override
	public Collection<Canvas> obterCanvasResponsavel(Perfil perfil) throws Exception {
		String sql = "SELECT c FROM Canvas c WHERE c.perfilResponsavel =:perfil ORDER BY c.titulo";

		Query query = em.createQuery(sql);
		query.setParameter("perfil", perfil);
		List<Canvas> canvas = query.getResultList();

		return canvas;
	}
	
	/**
	 * Método para retornar todos os CANVAS ao qual determinado perfil está participando
	 * @param PERFIL
	 * @return COLLECTION<CANVAS>
	 * @exception Exception
	 * */
	@Override
	public Collection<Canvas> obterCanvasParticipante(Perfil perfil) throws Exception {
		Collection<Long> listaId = obterIdCanvasParticipante(perfil);
		Collection<Canvas> canvas = estruturaCanvasPerfil(listaId);

		return canvas;
	}
	
	/**
	 * Método para de todos os CANVAS a partir de um PERFIL
	 * @param PERFIL
	 * @return COLLECTION<LONG>
	 * @exception Exception
	 * */
	@SuppressWarnings("unchecked")
	@Override
	public Collection<Long> obterIdCanvasParticipante(Perfil perfil) throws Exception {
		String sql = "SELECT c.id_canvas FROM CANVAS c " +
					 "INNER JOIN PARTICIPANTES AS p ON c.id_canvas = p.id_canvas " +
					 "INNER JOIN PERFIL AS pe ON p.id_perfil = pe.id_perfil " +
					 "WHERE pe.id_perfil = :id_perfil";
		
		Query query = em.createNativeQuery(sql);
		query.setParameter("id_perfil", perfil.getId());
		Collection<BigInteger> listaBI = query.getResultList();
		
		Collection<Long> lista = new ArrayList<>();
		for(BigInteger bi : listaBI){
			lista.add(bi.longValue());

		}
		
		return lista;
	}
	
	/**
	 * Método para buscar todos os CANVAS a partir de uma lista de IDs
	 * @param COLLECTION<LONG>
	 * @return COLLECTION<CANVAS>
	 * @exception Exception
	 * */
	@Override
	public Collection<Canvas> estruturaCanvasPerfil(Collection<Long> idCanvas) throws Exception {
		Collection<Canvas> result = new ArrayList<>();
		
		for(Long l : idCanvas){
			result.add(super.obterPorId(l));
		}

		return result;
	}
	
}
